//
//  VideoCacheManager.swift
//  Mediaplayer
//
//  Created by bin hu on 2025/7/11.
//

import UIKit

// MARK: - 视频缓存管理器
class VideoCacheManager {
    static let shared = VideoCacheManager()
    private let fileManager = FileManager.default
    private let cacheDirectory: URL
    private let cacheQueue = DispatchQueue(label: "com.videocache.queue", qos: .utility)
    private let maxCacheSize: Int64 = 500 * 1024 * 1024 // 500 MB
    
    private init() {
        let directories = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)
        cacheDirectory = directories[0].appendingPathComponent("VideoCache")
        
        // 创建缓存目录
        if !fileManager.fileExists(atPath: cacheDirectory.path) {
            try? fileManager.createDirectory(at: cacheDirectory, withIntermediateDirectories: true, attributes: nil)
        }
        
        // 清理旧缓存
        cleanCacheIfNeeded()
    }
    
    func cacheVideo(from url: URL) {
        // 如果已缓存则跳过
        if isCached(url: url) { return }
        
        cacheQueue.async {
            let task = URLSession.shared.downloadTask(with: url) { [weak self] location, response, error in
                guard let location = location, error == nil else { return }
                
                // 生成唯一文件名
                let fileName = url.absoluteString.md5 + ".mp4"
                let destination = self?.cacheDirectory.appendingPathComponent(fileName)
                
                // 移动文件到缓存目录
                if let destination = destination {
                    try? self?.fileManager.moveItem(at: location, to: destination)
                    
                    // 更新缓存元数据
                    self?.updateCacheMetadata(url: url, fileURL: destination)
                    
                    // 检查缓存大小
                    self?.cleanCacheIfNeeded()
                }
            }
            task.resume()
        }
    }
    
    func cachedFileURL(for url: URL) -> URL? {
        let fileName = url.absoluteString.md5 + ".mp4"
        let fileURL = cacheDirectory.appendingPathComponent(fileName)
        return fileManager.fileExists(atPath: fileURL.path) ? fileURL : nil
    }
    
    func isCached(url: URL) -> Bool {
        return cachedFileURL(for: url) != nil
    }
    
    func loadCachedVideos(for items: [VideoItem], completion: @escaping ([URL: VideoItem]) -> Void) {
        var cachedItems: [URL: VideoItem] = [:]
        
        cacheQueue.async {
            for item in items {
                if let fileURL = self.cachedFileURL(for: item.videoUrl) {
                    var cachedItem = item
                    cachedItem.isCached = true
                    cachedItem.localURL = fileURL
                    cachedItems[item.videoUrl] = cachedItem
                }
            }
            
            DispatchQueue.main.async {
                completion(cachedItems)
            }
        }
    }
    
    private func updateCacheMetadata(url: URL, fileURL: URL) {
        // 更新访问时间
        let attributes: [FileAttributeKey: Any] = [
            .modificationDate: Date()
        ]
        try? fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path)
    }
    
    func cleanCacheIfNeeded() {
        cacheQueue.async {
            let contents = (try? self.fileManager.contentsOfDirectory(
                at: self.cacheDirectory,
                includingPropertiesForKeys: [.contentModificationDateKey],
                options: .skipsHiddenFiles
            )) ?? []
            
            // 计算总缓存大小
            var totalSize: Int64 = 0
            var fileAttributes: [(url: URL, date: Date, size: Int64)] = []
            
            for url in contents {
                if let attributes = try? self.fileManager.attributesOfItem(atPath: url.path),
                   let fileSize = attributes[.size] as? Int64,
                   let modDate = attributes[.modificationDate] as? Date {
                    totalSize += fileSize
                    fileAttributes.append((url, modDate, fileSize))
                }
            }
            
            // 如果超过最大缓存大小，则清理
            if totalSize > self.maxCacheSize {
                // 按访问时间排序（最旧的在前面）
                fileAttributes.sort { $0.date < $1.date }
                
                var sizeToFree = totalSize - self.maxCacheSize
                for file in fileAttributes {
                    if sizeToFree <= 0 { break }
                    
                    try? self.fileManager.removeItem(at: file.url)
                    sizeToFree -= file.size
                }
            }
        }
    }
}
